<?php
/**
 * H5支付.
 */

namespace app\api\service\payment;

use app\api\service\ApiPayment;
use app\common\library\exception\OrderException;

class JianHangpay extends ApiPayment
{
    public function jianhangscanpay($order)
    {
        $bankURL = 'https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain';

        return $this->requestApi($bankURL, $order);
    }

    public function requestApi($url, $order)
    {
        $MERCHANTID = $this->config['MERCHANTID'];
        $POSID = $this->config['POSID'];
        $BRANCHID = $this->config['BRANCHID'];
        $PUB = $this->config['PUBKEY'];
        $RETURNTYPE = 1;

        $PUB = substr($PUB, -30); //PUB字段为对应柜台的公钥后30位

        //由商户提供，最长30位。需按以下规则生成订单号：商户代码(15位)+自定义字符串(不超过15位)。字符串可包含数字、字母、下划线。商户需保证订单号唯一。
        //需要修改订单号为最多15位的
        $trade_no = $order['trade_no'];
        $order_id = $MERCHANTID.$trade_no;
        $order_amt = bcmul($order['amount'], 1, 2); //转为高精度数字类型

        $sign = md5('MERCHANTID='.$MERCHANTID
            .'&POSID='.$POSID
            .'&BRANCHID='.$BRANCHID
            .'&ORDERID='.$order_id
            .'&PAYMENT='.$order_amt
            .'&CURCODE='.'01'
            .'&TXCODE='.'530550'
            .'&REMARK1='.''
            .'&REMARK2='.''
            .'&RETURNTYPE='.$RETURNTYPE
            .'&TIMEOUT='.''
            .'&PUB='.$PUB);

        $data = array(
            'CCB_IBSVersion' => 'V6',
            'MERCHANTID' => $MERCHANTID,
            'POSID' => $POSID,
            'BRANCHID' => $BRANCHID,
            'ORDERID' => $order_id,
            'PAYMENT' => $order_amt,
            'CURCODE' => '01',
            'TXCODE' => '530550',
            'REMARK1' => '',
            'REMARK2' => '',
            'RETURNTYPE' => $RETURNTYPE,
            'TIMEOUT' => '',
            'MAC' => $sign,
        );

        $result = self::curl($url, $data); // 发起远程请求
        $res = json_decode($result);
        if ('true' == $res->SUCCESS) {
            $codeStr = file_get_contents($res->PAYURL);
            $code = json_decode($codeStr);
            if ($code->SUCCESS = 'true') {
                $qrUrl = 'https://ibsbjstar.ccb.com.cn/CCBIS/QrcodeServlet?width=185&height=185&qrcode=https%3A%2F%2Fibsbjstar.ccb.com.cn%2FCCBIS%2FQR%3FQRCODE%3DCCB'.$code->QRURL;
                $fileName = date('Ymd').DS.date('His').str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT).'.png';

                if (!file_exists(UPLOAD_PATH.'qr')) {
                    mkdir(UPLOAD_PATH.'qr', 0777, true);
                }

                if (!file_exists(UPLOAD_PATH.'qr'.DS.date('Ymd'))) {
                    mkdir(UPLOAD_PATH.'qr'.DS.date('Ymd'), 0777, true);
                }

                mergeImg($qrUrl, STATIC_PATH.'common/logo-qr.png', UPLOAD_PATH.DS.'qr/'.$fileName);

                $orderInstance = new \app\common\model\Orders();
                $orderInstance->changeOrderStatusValue([
                    'ch_result' => $result,
                    'qr_img' => 'qr/'.$fileName,
                ], [
                    'id' => $order->id,
                ]);

                return [
                    'order_id' => $order['out_trade_no'],
                    'pay_seq' => $order['trade_no'],
                    'pay_url' => UPLOAD_URL.'qr/'.$fileName,
                ];
            }
        }

        throw new OrderException([
            'msg' => $res->status_msg,
            'errCode' => $res->status_code,
        ]);
    }

    public function notify()
    {
        return $this->verifyOrderNotify();
    }

    /**
     * 回调验签.
     *
     *
     * @return array
     *
     * @throws OrderException
     */
    private function verifyOrderNotify()
    {
        //默认商户ID
        $MERCHANTID = '105002053991265';
        if (preg_match("/\d+/", $_REQUEST['s'], $matches) && isset($matches[0])) {
            $MERCHANTID = $matches[0];
        }

        $requestUri = explode("?", $_SERVER['REQUEST_URI']);
        if (!$this->checkSig($requestUri[1])) {
            return false;
        }

        $ORDERID = \think\Request::instance()->param('ORDERID');
        $SUCCESS = \think\Request::instance()->param('SUCCESS');
        if (strtoupper(trim($SUCCESS)) != "Y") {
            return false;
        }

        return array(
            'trade_no' => substr($ORDERID, strlen($MERCHANTID)),
        );
    }

    public static function curl($url = '', $postData = '')
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090803 Fedora/3.5.2-2.fc11 Firefox/3.5.2');
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('content-type: application/x-www-form-urlencoded;charset=utf-8'));

        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $data = curl_exec($ch);

        curl_close($ch);

        $data = mb_convert_encoding($data, 'utf-8', 'gb2312');

        return $data;
    }

    /**
     * 使用Java服务校验验证码
     */
    public function checkSig($data, $address = "127.0.0.1", $port = 55533)
    {
        return true;
        $data  .= "\n";
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket < 0) {
            return false;
        }

        $result = socket_connect($socket, $address, $port);
        if ($result < 0) {
            return false;
        }

        $res = '';
        socket_write($socket, $data, strlen($data));
        while ($out = socket_read($socket, 2048)) {
            $res .= $out;
        }

        socket_close($socket);
        return (strtoupper(substr($res, 0, 1)) == "Y") ? true : false;
    }

    /**
     * 回调成功参数
     */
    public function callbackSuccessResponse()
    {
        return "0000";
    }
}
